<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Rax Playground</title>
    <link rel="stylesheet" type="text/css" href="//unpkg.com/normalize.css@5.0.0" />
    <link rel="stylesheet" type="text/css" href="//unpkg.com/codemirror@5.20.2/lib/codemirror.css" />
    <style>

    .cm-s-default {
      background-color: #f9f9f9;
    }

    .cm-s-dark {
      background-color: #1e1d23;
      color: rgba(233, 237, 237, 1);
    }

    .cm-s-dark .CodeMirror-gutters {
      background-color: #1e1d23;
      color: rgb(83,127,126);
      border: none;
    }
    .cm-s-dark .CodeMirror-guttermarker, .cm-s-dark .CodeMirror-guttermarker-subtle, .cm-s-dark .CodeMirror-linenumber { color: #999; }
    .cm-s-dark .CodeMirror-cursor { border-left: 1px solid #f8f8f0; }
    .cm-s-dark div.CodeMirror-selected { background: rgba(255, 255, 255, 0.15); }
    .cm-s-dark.CodeMirror-focused div.CodeMirror-selected { background: rgba(255, 255, 255, 0.10); }
    .cm-s-dark .CodeMirror-line::selection, .cm-s-dark .CodeMirror-line > span::selection, .cm-s-dark .CodeMirror-line > span > span::selection { background: rgba(255, 255, 255, 0.10); }
    .cm-s-dark .CodeMirror-line::-moz-selection, .cm-s-dark .CodeMirror-line > span::-moz-selection, .cm-s-dark .CodeMirror-line > span > span::-moz-selection { background: rgba(255, 255, 255, 0.10); }

    .cm-s-dark .CodeMirror-activeline-background { background: rgba(0, 0, 0, 0); }
    .cm-s-dark .cm-keyword { color: rgba(199, 146, 234, 1); }
    .cm-s-dark .cm-operator { color: rgba(233, 237, 237, 1); }
    .cm-s-dark .cm-variable-2 { color: #80CBC4; }
    .cm-s-dark .cm-variable-3 { color: #82B1FF; }
    .cm-s-dark .cm-builtin { color: #DECB6B; }
    .cm-s-dark .cm-atom { color: #F77669; }
    .cm-s-dark .cm-number { color: #F77669; }
    .cm-s-dark .cm-def { color: rgba(233, 237, 237, 1); }
    .cm-s-dark .cm-string { color: #C3E88D; }
    .cm-s-dark .cm-string-2 { color: #80CBC4; }
    .cm-s-dark .cm-comment { color: #546E7A; }
    .cm-s-dark .cm-variable { color: #82B1FF; }
    .cm-s-dark .cm-tag { color: #80CBC4; }
    .cm-s-dark .cm-meta { color: #80CBC4; }
    .cm-s-dark .cm-attribute { color: #FFCB6B; }
    .cm-s-dark .cm-property { color: #80CBAE; }
    .cm-s-dark .cm-qualifier { color: #DECB6B; }
    .cm-s-dark .cm-variable-3 { color: #DECB6B; }
    .cm-s-dark .cm-tag { color: rgba(255, 83, 112, 1); }
    .cm-s-dark .cm-error {
      color: rgba(255, 255, 255, 1.0);
      background-color: #EC5F67;
    }
    .cm-s-dark .CodeMirror-matchingbracket {
      text-decoration: underline;
      color: white !important;
    }
    </style>

    <style>
    body {
      margin: 0;
    }

    #editor {
      display: none;
    }

    .container {
      position: absolute;;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      display: flex;
      flex-direction: column;
    }

    .action-bar {
      background-color: #3d3d3e;
      height: 40px;
      display: flex;
    }

    .playground {
      display: flex;
      flex-direction: row;
      flex: 1;
    }

    .editor {
      overflow: scroll;
      flex: 1;
    }

    .CodeMirror {
      height: 100%;
    }

    .preview {
      position: relative;
      height: 100vh;
      display: flex;
      align-items: center;
      justify-content: center;
      overflow: hidden;;
    }

    .phone {
      flex: 1;
      width: 420px;
      height: 858px;
      background-image: url(./images/iphone.png);
      background-size: contain;
      background-repeat: no-repeat;
      opacity: 0;
      transition: opacity 1s;
    }

    .frame {
      position: absolute;
      top: 90px;
      left: 22px;
      border: 0;
      height: 667px;
      width: 375px;
      background-color: #fff;
    }

    .notification {
      position: absolute;;
      z-index: 1000;
      bottom: 10px;
      left: 40px;
      background: rgba(61, 61, 62, 0.7);
      min-width: 280px;
      max-width: 700px;
      border-radius: 5px;
    }

    .notification.hide {
      display: none;
    }

    .notification-content {
      margin: 12px;
      font-size: 10px;
      line-height: 1.4;
      color: #ddd;
    }
    </style>
  </head>
<body>

<div class="container">
  <div class="playground">
    <div class="editor">
      <textarea id="editor">
import {createElement, Component, render} from 'rax';
import {View, Text} from 'rax-components';

class App extends Component {
  render() {
    return <View style={styles.container}>
      <Text>Hello world</Text>
    </View>;
  }
}

const styles = {
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  }
};

render(<App />);</textarea>
    </div>
    <div class="preview">
      <div class="phone" id="phone">
        <iframe class="frame" id="frame"></iframe>
      </div>
    </div>
  </div>

  <div class="notification hide" id="notification">
    <pre class="notification-content" id="notification-content"></pre>
  </div>
</div>

<script src="//unpkg.com/babel-standalone@6.18.2/babel.min.js"></script>
<script src="//unpkg.com/codemirror@5.20.2/lib/codemirror.js"></script>
<script src="//unpkg.com/codemirror@5.20.2/mode/xml/xml.js"></script>
<script src="//unpkg.com/codemirror@5.20.2/mode/javascript/javascript.js"></script>
<script src="//unpkg.com/codemirror@5.20.2/mode/jsx/jsx.js"></script>

<script>
  function getQueryString() {
    var result = {};
    var queryString = location.search.slice(1);
    var re = /([^&=]+)=([^&]*)/g
    var m;

    while (m = re.exec(queryString)) {
      result[decodeURIComponent(m[1])] = decodeURIComponent(m[2]);
    }

    return result;
  }

  var queryString = getQueryString();
  var sourceFromQueryString = queryString.code;
  var backgroundColor = queryString.bgColor;
  var editorTheme = queryString.theme || 'dark';

  var notification = document.getElementById('notification');
  var notificationContent = document.getElementById('notification-content');
  var frame = document.getElementById('frame');
  var phone = document.getElementById('phone');

  var storageKey = 'rax:playground:source';
  var myTextarea = document.getElementById('editor');
  var editor = CodeMirror.fromTextArea(myTextarea, {
    lineNumbers: true,
    theme: editorTheme,
    tabSize: 2,
    mode: 'jsx',
  });


  var lastStorageSource = localStorage.getItem(storageKey);
  var source = sourceFromQueryString || lastStorageSource || editor.getValue();

  if (editorTheme === 'dark') {
    var style = document.createElement('style');
    style.innerHTML = '.container {background-color: #1e1d23}';
    document.body.appendChild(style);
  }

  if (source) {
    editor.setValue(source);
    compile(source, true);
  }

  // Auto adjust device scale
  var windowHeight = window.innerHeight;
  var phoneHeight = 858;
  var scale = windowHeight / phoneHeight;
  scale = scale > 1 ? 1 : scale;
  phone.style.transform = 'scale(' + scale + ')';
  phone.style.opacity = 1;

  function hideNotify() {
    notification.classList.add('hide');
  }

  var lastTimer;
  function showNotify(message, time) {
    notificationContent.innerHTML = message;
    notification.classList.remove('hide');

    if (lastTimer) {
      clearTimeout(lastTimer);
    }

    if (time) {
      lastTimer = setTimeout(hideNotify, time);
    }
  }

  var isReady = false;
  var lastCode;
  var lastScript;

  // Listen to frame
  window.onmessage = function(e) {
    var data;
    try {
      data = JSON.parse(e.data);
    } catch (err) {
      return;
    }

    switch (data.type) {
      case 'ready':
        isReady = true;
        compile(lastCode);
      break;
      case 'error':
        showNotify(data.message);
      break
    }
  }

  frame.src = "./player.html";

  function runCompiled(code) {

    var body = frame.contentDocument.body;
    if (lastScript) {
      body.removeChild(lastScript);
      body.innerHTML = '';
    }

    var script = document.createElement("script");
    script.innerHTML = code;
    lastScript = script;

    body.appendChild(script);
  }

  function compile(input, isInit) {

    input = input || '';
    lastCode = input;
    hideNotify();

    var paramComment = '/* @jsx createElement */\n';
    try {
      var output = Babel.transform(paramComment + input, { presets: ["es2015", "react", "stage-1"] }).code;
    } catch(e){
      console.error(e);
      showNotify(e);
      return;
    }

    if (!isReady) {
      !isInit && showNotify('Player is not ready!', 3000);
      return;
    }

    runCompiled(output);
  }

  // Bactched
  editor.on("changes", function(editor){
    var input = editor.getValue();
    compile(input);
    localStorage.setItem(storageKey, input);
  });

</script>
</body>
</html>
